package org.lalib.controller.action;

import java.util.ArrayList;
import java.util.List;

import org.lalib.acquire.IControllerAction;
import org.lalib.controller.form.CUserTableMatchForm;
import org.lalib.controller.form.CUserTableMatchForm.TableMatchBean;
import org.lalib.controller.service.CTableService;
import org.lalib.controller.service.CUserService;
import org.lalib.entity.object.EItem;
import org.lalib.entity.object.ETable;
import org.lalib.entity.object.EUser;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;

@Scope("request")
@Controller("cUserTableMatchAction")
public class CUserTableMatchAction implements IControllerAction {

	@Autowired
	private CUserTableMatchForm cUserTableMatchForm;

	@Autowired
	private CTableService cTableService;

	@Autowired
	private CUserService cUserService;

	private static final long serialVersionUID = 1L;

	public String init(EItem item) {
		EUser user = (EUser) item;
		cUserTableMatchForm.setUser(user);
		List<ETable> allTables = cTableService.getAllTables();
		resetVariables(user, allTables);
		return "userTableMatchDefination";
	}

	private void resetVariables(EUser user, List<ETable> allTables) {
		user = (EUser) cUserService.getUserById(user.getId());
		cUserTableMatchForm.setTables(allTables);
		List<ETable> includedTables = user.getTables();
		List<ETable> excludedTables = filterTables(allTables, includedTables);
		cUserTableMatchForm.setExcludedTableBeans(getTableMatchBeansForGivenTables(excludedTables));
		cUserTableMatchForm.setIncludedTableBeans(getTableMatchBeansForGivenTables(includedTables));
	}

	public void addToUser() {
		List<TableMatchBean> excludedBeans = cUserTableMatchForm.getExcludedTableBeans();
		EUser user = cUserTableMatchForm.getUser();
		user = cUserService.getUserById(user.getId());
		boolean check = false;
		for (TableMatchBean tableMatchBean : excludedBeans) {
			if (tableMatchBean.isSelected()) {
				user.getTables().add(tableMatchBean.getTable());
				check = true;
			}
		}

		if (check) {
			cUserService.update(user);
			resetVariables(user, cUserTableMatchForm.getTables());
		}
	}

	public void removeFromUser() {
		List<TableMatchBean> selectedBeans = cUserTableMatchForm.getIncludedTableBeans();
		EUser user = cUserTableMatchForm.getUser();
		user = cUserService.getUserById(user.getId());
		boolean check = false;

		for (TableMatchBean tableMatchBean : selectedBeans) {
			if (tableMatchBean.isSelected()) {
				deleteUserTableForTable(user, tableMatchBean.getTable());
				check = true;
			}
		}

		if (check) {
			cUserService.update(user);
			resetVariables(user, cUserTableMatchForm.getTables());
		}
	}

	private List<TableMatchBean> getTableMatchBeansForGivenTables(List<ETable> tables) {
		List<TableMatchBean> tableMatchBeans = new ArrayList<>();
		for (ETable table : tables)
			tableMatchBeans.add(cUserTableMatchForm.new TableMatchBean(table));
		return tableMatchBeans;
	}

	private List<ETable> filterTables(List<ETable> allTables, List<ETable> includedTables) {
		List<ETable> excludedTables = new ArrayList<>();
		for (ETable table : allTables) {
			boolean check = true;
			for (ETable eTable : includedTables) {
				if (eTable.getId().equals(table.getId())) {
					check = false;
					break;
				}
			}
			if (check) {
				excludedTables.add(table);
			}
		}
		return excludedTables;
	}

	private void deleteUserTableForTable(EUser user, ETable table) {
		int id = 0;
		boolean found = false;

		for (int i = 0; i < user.getTables().size(); i++) {
			if (user.getTables().get(i).getId().equals(table.getId())) {
				id = i;
				found = true;
			}
		}
		if (found)
			user.getTables().remove(id);
	}
}